import { ref, unref, watch, WatchStopHandle } from 'vue';
import { BasicTableProps, DynamicProps, FetchParams, TableActionType, Nullable } from '../types';
import { getDynamicProps } from '../utils';

type Props = Partial<DynamicProps<BasicTableProps>>;

export function useTable(tableProps?: Props) {
  let stopWatch: WatchStopHandle;
  const tableRef = ref<Nullable<TableActionType>>(null);
  const loadedRef = ref<Nullable<boolean>>(false);
  function register(instance: TableActionType) {
    if (unref(loadedRef) && instance === unref(tableRef)) return;

    tableRef.value = instance;
    tableProps && instance.setProps(getDynamicProps(tableProps));
    loadedRef.value = true;

    stopWatch?.();

    stopWatch = watch(
      () => tableProps,
      () => {
        tableProps && instance.setProps(getDynamicProps(tableProps));
      },
      {
        immediate: true,
        deep: true,
      },
    );
  }
  function getTableInstance(): TableActionType {
    const table = unref(tableRef);
    if (!table) {
      console.error(
        'The table instance has not been obtained yet, please make sure the table is presented when performing the table operation!',
      );
    }
    return table as TableActionType;
  }
  const methods: TableActionType = {
    reload: async (opt?: FetchParams) => {
      return await getTableInstance().reload(opt);
    },
    getData: () => {
      return getTableInstance().getData();
    },
    clearSelection: () => {
      return getTableInstance().clearSelection();
    },
    getSelectionRows: () => {
      return getTableInstance().getSelectionRows();
    },
    toggleAllSelection: () => {
      return getTableInstance().toggleAllSelection();
    },
    toggleRowSelection: (row, selected) => {
      return getTableInstance().toggleRowSelection(row, selected);
    },
    setExpandRowKeys: (rowKeys) => {
      return getTableInstance().setExpandRowKeys(rowKeys);
    },
    getSearchInfo: () => {
      return getTableInstance().getSearchInfo();
    },
    setFormItems: (value) => {
      return getTableInstance().setFormItems(value);
    },
    setFormData: (value) => {
      return getTableInstance().setFormData(value);
    },
  };

  return { register, methods };
}
